package cn.ad.service;

import cn.ad.exception.AdTemplateValidateException;
import cn.ad.handler.SqlSessionHandler;
import cn.ad.enumration.MaterialFormat;
import cn.ad.enumration.MaterialType;
import cn.ad.interceptor.PageParameter;
import cn.ad.model.*;
import cn.ad.entity.AdSize;
import cn.ad.entity.AdTemplateSpec;
import com.alibaba.druid.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 原生模版 服务层实现
 * 
 * @author yujuan.zhang
 * @from 2016-06-17
 * @since V1.0
 *
 */
@Service
public class AdTemplateService {
	
	@Autowired
	private SqlSessionHandler sqlSessionHandler;

	/**
	 * 获取原生模版下拉列表
	 */
	public List<AdTemplateDropDownModel> getAdTemplateList() {
		return sqlSessionHandler.selectList("adTemplateMapper.adTemplate:list", null);
	}

	/***
	 * 新增原生模版
	 */
	@Transactional
	public void addAdTemplate(AdTemplateDetailModel adTemplateDetailModel) {
		// 模版名称重复验证
		if (hasAdTemplate(adTemplateDetailModel)) {
			throw new AdTemplateValidateException(AdTemplateValidateException.ErrorCode.ADTEMPLATE_REPEAT);
		}

		// 写入模版表同时返回模版ID
		sqlSessionHandler.insert("adTemplateMapper.insert", adTemplateDetailModel);

		// 写入模版元素表
		if (!CollectionUtils.isEmpty(adTemplateDetailModel.getAdTemplateSpecList())) {
			for (AdTemplateSpecDetailModel adTemplateSpecDetailModel : adTemplateDetailModel.getAdTemplateSpecList()) {
				// 设置模版ID
				adTemplateSpecDetailModel.setTemplateId(adTemplateDetailModel.getId());
				
				// 设置所支持的图片格式, 在广告位模块操作
				// 元素类型为文本时，设置format_type为文本
				if (adTemplateSpecDetailModel.getElementType() == MaterialType.MATERIALTYPE_TEXT.getValue()) {
					adTemplateSpecDetailModel.setFormatType(Integer.toString(MaterialFormat.MATERIALFORMAT_TEXT.getValue()));
				}
				
				// 元素类型为图片时，关联ad_size表，设置尺寸信息
				setAdTemplateSpecForPictureElement(adTemplateSpecDetailModel);
				
				// 写入模版元素表
				sqlSessionHandler.insert("adTemplateSpecMapper.insert", adTemplateSpecDetailModel);
			}
		}
	}

	// 原生模版元素类型为图片时，关联ad_size表，设置尺寸信息
	private void setAdTemplateSpecForPictureElement(AdTemplateSpecDetailModel adTemplateSpecDetailModel) {
		// 元素类型为图片时，关联ad_size表
		if (adTemplateSpecDetailModel.getElementType() == MaterialType.MATERIALTYPE_PICTURE.getValue()) {
			// 根据width和height查询ad_size表是否存在该尺寸
			Map<String, Object> mapParams = new HashMap<>();
			mapParams.put("width", adTemplateSpecDetailModel.getWidth());
			mapParams.put("height", adTemplateSpecDetailModel.getHeight());
			AdSize adSize = sqlSessionHandler.selectOne("adSizeMapper.select:by:width:and:height", mapParams);
			
			if (adSize == null) { 
				// 如果不存在，则写入到ad_size表并返回id
				adSize = new AdSize();
				adSize.setName(new StringBuilder("").append(adTemplateSpecDetailModel.getWidth()).append("x").append(adTemplateSpecDetailModel.getHeight()).toString());
				adSize.setWidth(adTemplateSpecDetailModel.getWidth());
				adSize.setHeight(adTemplateSpecDetailModel.getHeight());
				sqlSessionHandler.insert("adSizeMapper.insert", adSize);
			}
			
			// 设置ad_size_id关联ad_size表
			adTemplateSpecDetailModel.setAdSizeId(adSize.getId());
		}
	}

	/**
	 * 模版名称重复验证
	 * 
	 * @param adTemplateDetailModel
	 * @return
	 */
	private boolean hasAdTemplate(AdTemplateDetailModel adTemplateDetailModel) {
		return (int) sqlSessionHandler.selectOne("adTemplateMapper.adTemplate:checkname", adTemplateDetailModel) > 0;
	}

	/**
	 * 根据模版ID查询单个模版的详细信息
	 */
	public AdTemplateDetailModel selectAdTemplateDetailById(Integer id) {
		return sqlSessionHandler.selectOne("adTemplateMapper.selectById", id);
	}

	/**
	 * 查询原生模版列表
	 */
	public ResultSetList<AdTemplateModel> findAdTemplateModels(Map<String, Object> searchMap, PageParameter pageInfo) {
		List<AdTemplateModel> adTemplateModelList = sqlSessionHandler.selectList("adTemplateMapper.adTemplateModel:list:page", searchMap, pageInfo);
		//判断查询集合结果是否为空
		if(this.isNotNull(adTemplateModelList)) {
			StringBuilder sb = null;
			//循环查询集合结果 ->>元素标识 转换成对应的描述
			for(AdTemplateModel adTemplateModel : adTemplateModelList) {
				String elementDes = adTemplateModel.getElementDes();
				if(!StringUtils.isEmpty(elementDes)) {
					String[] elements = elementDes.split(",");
					sb = new StringBuilder("");
					for(String element : elements) {
						if(MaterialType.MATERIALTYPE_VIDEO.getValue() == Integer.parseInt(element)) {
							sb.append(MaterialType.MATERIALTYPE_VIDEO.getDescription()).append(",");
						}
						if(MaterialType.MATERIALTYPE_TEXT.getValue() == Integer.parseInt(element)) {
							sb.append(MaterialType.MATERIALTYPE_TEXT.getDescription()).append(",");
						}
						if(MaterialType.MATERIALTYPE_PICTURE.getValue() == Integer.parseInt(element)) {
							sb.append(MaterialType.MATERIALTYPE_PICTURE.getDescription()).append(",");
						}
					}
					if(sb.length() > 0) {
						adTemplateModel.setElementDes(sb.toString().substring(0, sb.length() - 1));
					}
				}else {
					adTemplateModel.setElementDes("");
				}
			}
		}
		ResultSetList<AdTemplateModel> list = new ResultSetList<AdTemplateModel>(pageInfo.getTotalCount(), adTemplateModelList); 
		return list;
	}

	/**
	 * 判断list集合是否为空
	 * @param list
	 * @return
	 */
	private boolean isNotNull(List list) {
		if(!CollectionUtils.isEmpty(list) && list.size() > 0) {
			return true;
		}
		return false;
	}

	/**
	 * 根据模版ID 逻辑删除模版
	 * @param id
	 * @return
	 */
	public boolean deleteAdTemplateById(int id) {
		if(!this.hasAdSpaceUsed(id)) {
			Map<String, Object> params = new HashMap<>();
			params.put("id", id);
			params.put("status", -1);
			if(sqlSessionHandler.update("adTemplateMapper.update", params) > 0) {
				return true;
			}
		}
		return false;
	}
	/**
	 * 查询模版是否有被广告位使用
	 * @param id
	 * @return
	 */
	public boolean hasAdSpaceUsed(int id) {
		return  (int)sqlSessionHandler.selectOne("adTemplateMapper.adTemplate:associated:with:adspace", id) > 0;
	}
	 /**
	  * 根据供应商ID
	 * 获取原生模版下拉列表
	 * @return
	 */
	public List<AdTemplateDropDownModel> getAdTemplateList(Map<String, Integer> queryMap){
		return sqlSessionHandler.selectList("adTemplateMapper.adTemplate:auth:list", queryMap);
	}
	
	/***
	 * 编辑原生模版
	 */
	@Transactional
	public void editAdTemplate(AdTemplateDetailModel adTemplateDetailModel) {
		boolean isUsedByAdSpace = hasAdSpaceUsed(adTemplateDetailModel.getId());
		
		// 模版名称重复验证
		if (hasAdTemplate(adTemplateDetailModel)) {
			throw new AdTemplateValidateException(AdTemplateValidateException.ErrorCode.ADTEMPLATE_REPEAT);
		}
	
		Map<String, Object> adTemplateDetailParams = new HashMap<>();
		adTemplateDetailParams.put("id", adTemplateDetailModel.getId());
		adTemplateDetailParams.put("name", adTemplateDetailModel.getName());
		adTemplateDetailParams.put("sampleUrl", adTemplateDetailModel.getSampleUrl());
		adTemplateDetailParams.put("description", adTemplateDetailModel.getDescription());
		adTemplateDetailParams.put("supplierId", adTemplateDetailModel.getSupplierId());
		adTemplateDetailParams.put("platformId", adTemplateDetailModel.getPlatformId());
		// 是否被广告位使用
		adTemplateDetailParams.put("isUsedByAdSpace", isUsedByAdSpace);
		
		// 已经被广告位使用的模版只能修改名称，示列图，备注和元素的显示名称
		// 没有被广告位使用的模版都可以编辑
		sqlSessionHandler.update("adTemplateMapper.update:adtemplate", adTemplateDetailParams);

		// 逻辑删除该模版下的所有元素
		Map<String, Object> param = new HashMap<>();
		param.put("templateId", adTemplateDetailModel.getId());
		sqlSessionHandler.update("adTemplateSpecMapper.delete:logic", param);

		// 修改模版元素
		if (adTemplateDetailModel.getAdTemplateSpecList() != null) {
			for (AdTemplateSpecDetailModel adTemplateSpecDetailModel : adTemplateDetailModel.getAdTemplateSpecList()) {

				adTemplateSpecDetailModel.setTemplateId(adTemplateDetailModel.getId());
				// 元素类型为文本时，设置format_type为文本
				if (adTemplateSpecDetailModel.getElementType() == MaterialType.MATERIALTYPE_TEXT.getValue()) {
					adTemplateSpecDetailModel.setFormatType(Integer.toString(MaterialFormat.MATERIALFORMAT_TEXT.getValue()));
				}
				
				// 元素类型为图片时，关联ad_size表，设置尺寸信息
				setAdTemplateSpecForPictureElement(adTemplateSpecDetailModel);

				// 查询该模版下是否已存在状态为删除的该index_value, 有则update，无则insert
				Map<String, Object> adTemplateSpecParam = new HashMap<>();
				adTemplateSpecParam.put("indexValue", adTemplateSpecDetailModel.getIndexValue());
				adTemplateSpecParam.put("templateId", adTemplateDetailModel.getId());
				AdTemplateSpec adTemplateSpecAlreadyExist = sqlSessionHandler.selectOne("adTemplateSpecMapper.select:exist:index:value", adTemplateSpecParam);
				
				if (adTemplateSpecAlreadyExist != null) {
					adTemplateSpecDetailModel.setId(adTemplateSpecAlreadyExist.getId());
					sqlSessionHandler.update("adTemplateSpecMapper.update:adtemplatespec", adTemplateSpecDetailModel);
				} else {
					sqlSessionHandler.insert("adTemplateSpecMapper.insert", adTemplateSpecDetailModel);
				}
			}
		}
	}
			
}
